﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace com.ReinforceLab.AudioModem
{
    /// <summary>
    /// Sin tone generator, use this for test
    /// </summary>
    public class ToneSignalSource : IAudioSource
    {
        #region Variables
        readonly IAudioPHY _phy;
        readonly int _toneFreq;
        readonly double _dphai;
        readonly short[] _buffer;

        short _amplitude;
        
        double _phase;        
        #endregion

        #region Property
        public short Amplitude 
        {
            get { return _amplitude; }
            set { _amplitude = value; }
        }
        #endregion

        #region Public methods
        public ToneSignalSource(IAudioPHY phy, int toneFreq, short amplitude)
        {            
            if (phy == null)
                throw new ArgumentNullException("phy");           
            if (toneFreq <= 0 || toneFreq > phy.SamplingRate/ 2)
                throw new ArgumentOutOfRangeException("toneFreq");

            _phy = phy;            
            _toneFreq     = toneFreq;            
            _buffer       = new short[_phy.BufferLength];

            _amplitude = amplitude;

            _dphai = 2 * Math.PI * (double)_toneFreq / (double)_phy.SamplingRate;
            _phase = 0;
        }
        #endregion       

        #region IAudioConnector メンバ
        public void InSignal(short[] waveform, int validLength)
        {
            // do nothing
        }
        public short[] OutSignal(out int validLength)
        {
            for (int i = 0; i < _buffer.Length; i++)
            {
                _phase += _dphai;
                _buffer[i] = (short)(Math.Sin(_phase) * _amplitude);
            }
            
            validLength = _buffer.Length;
            return _buffer;
        }
        #endregion
    }
}
